/**
 * Java流程控制语句教学案例
 * 本案例演示了Java中各种流程控制语句的使用方法和注意事项
 */
public class ControlFlowExample {
    
    public static void main(String[] args) {
        ControlFlowExample example = new ControlFlowExample();
        
        example.demonstrateIfStatements();           // if语句演示
        example.demonstrateSwitchCase();             // switch-case语句演示
        example.demonstrateWhileLoop();              // while循环演示
        example.demonstrateDoWhileLoop();            // do-while循环演示
        example.demonstrateForLoop();                // for循环演示
        example.demonstrateEnhancedForLoop();        // 增强for循环演示
        example.demonstrateNestedLoops();            // 循环嵌套演示
        example.demonstrateJumpStatements();         // 跳转语句演示
    }
    
    /**
     * 演示if语句的使用
     * 难点：if-else if-else语句的执行逻辑和条件判断顺序
     * 注意事项：
     * 1. if语句可以单独使用，也可以与else或else if组合使用
     * 2. 多个条件判断时要注意条件的顺序，避免逻辑错误
     */
    public void demonstrateIfStatements() {
        System.out.println("=== if语句演示 ===");
        
        // 简单if语句
        int score = 85;
        System.out.println("分数: " + score);
        
        if (score >= 90) {
            System.out.println("优秀");
        } else if (score >= 80) {
            System.out.println("良好");
        } else if (score >= 60) {
            System.out.println("及格");
        } else {
            System.out.println("不及格");
        }
        
        // if语句中的逻辑运算符使用
        int age = 25;
        boolean hasLicense = true;
        System.out.println("\n年龄: " + age + ", 有驾照: " + hasLicense);
        
        // 难点：逻辑运算符的短路特性
        if (age >= 18 && hasLicense) {
            System.out.println("可以合法驾驶");
        }
        
        System.out.println();
    }
    
    /**
     * 演示switch-case语句的使用
     * 难点：switch语句的穿透特性及break语句的重要性
     * 注意事项：
     * 1. switch表达式必须是byte、short、int、char、String或枚举类型
     * 2. 每个case后如果没有break语句会发生穿透执行
     * 3. default语句不是必须的，但建议加上处理异常情况
     */
    public void demonstrateSwitchCase() {
        System.out.println("=== switch-case语句演示 ===");
        
        // 基本switch-case使用
        int dayOfWeek = 3;
        System.out.println("星期几: " + dayOfWeek);
        
        switch (dayOfWeek) {
            case 1:
                System.out.println("星期一");
                break;
            case 2:
                System.out.println("星期二");
                break;
            case 3:
                System.out.println("星期三");
                break;
            case 4:
                System.out.println("星期四");
                break;
            case 5:
                System.out.println("星期五");
                break;
            case 6:
                System.out.println("星期六");
                break;
            case 7:
                System.out.println("星期日");
                break;
            default:
                System.out.println("无效的星期数");
                break;
        }
        
        // switch语句穿透演示（缺少break的情况）
        System.out.println("\nswitch穿透演示:");
        char grade = 'B';
        System.out.println("成绩等级: " + grade);
        
        switch (grade) {
            case 'A':
                System.out.println("优秀");
            case 'B':  // 没有break，会继续执行下面的语句
                System.out.println("良好");
            case 'C':
                System.out.println("中等");
                break;  // 在这里跳出
            default:
                System.out.println("不及格");
        }
        
        System.out.println();
    }
    
    /**
     * 演示while循环的使用
     * 难点：循环条件的设置和循环变量的更新
     * 注意事项：
     * 1. 必须确保循环条件在某个时刻会变为false，否则会造成无限循环
     * 2. 循环变量的更新语句不能遗漏
     */
    public void demonstrateWhileLoop() {
        System.out.println("=== while循环演示 ===");
        
        // 基本while循环
        int i = 1;
        System.out.println("打印1到5的数字:");
        while (i <= 5) {
            System.out.print(i + " ");
            i++;  // 循环变量更新，避免无限循环
        }
        System.out.println();
        
        // while循环计算阶乘
        int n = 5;
        int factorial = 1;
        int j = 1;
        System.out.println("\n计算" + n + "的阶乘:");
        while (j <= n) {
            factorial *= j;
            j++;
        }
        System.out.println(n + "! = " + factorial);
        
        System.out.println();
    }
    
    /**
     * 演示do-while循环的使用
     * 难点：do-while与while循环的区别（至少执行一次）
     * 注意事项：
     * 1. do-while循环至少会执行一次循环体
     * 2. 循环条件在循环体执行后判断
     */
    public void demonstrateDoWhileLoop() {
        System.out.println("=== do-while循环演示 ===");
        
        // do-while循环至少执行一次
        int num = 0;
        System.out.println("do-while循环演示（条件为false）:");
        do {
            System.out.print(num + " ");
            num++;
        } while (num < 0);  // 条件为false，但循环体仍会执行一次
        System.out.println();
        
        // 用户输入验证场景
        java.util.Scanner scanner = new java.util.Scanner(System.in);
        int userInput;
        System.out.println("\n请输入一个1-10之间的数字:");
        do {
            System.out.print("输入: ");
            userInput = scanner.nextInt();
            if (userInput < 1 || userInput > 10) {
                System.out.println("输入无效，请输入1-10之间的数字！");
            }
        } while (userInput < 1 || userInput > 10);
        
        System.out.println("您输入的有效数字是: " + userInput);
        System.out.println();
    }
    
    /**
     * 演示for循环的使用
     * 难点：for循环三个表达式的执行顺序和作用
     * 注意事项：
     * 1. for循环的三个表达式都是可选的，可以省略
     * 2. 初始化表达式只执行一次
     * 3. 条件表达式每次循环都会检查
     * 4. 迭代表达式每次循环体执行完后执行
     */
    public void demonstrateForLoop() {
        System.out.println("=== for循环演示 ===");
        
        // 基本for循环
        System.out.println("打印1到10的数字:");
        for (int i = 1; i <= 10; i++) {
            System.out.print(i + " ");
        }
        System.out.println();
        
        // for循环计算1到100的和
        int sum = 0;
        System.out.println("\n计算1到100的和:");
        for (int i = 1; i <= 100; i++) {
            sum += i;
        }
        System.out.println("1到100的和为: " + sum);
        
        // 复杂for循环（多个变量）
        System.out.println("\n复杂for循环演示:");
        for (int i = 1, j = 10; i <= 5; i++, j--) {
            System.out.println("i = " + i + ", j = " + j);
        }
        
        System.out.println();
    }
    
    /**
     * 演示增强for循环（for-each）的使用
     * 难点：增强for循环与普通for循环的区别及适用场景
     * 注意事项：
     * 1. 增强for循环不能获取数组或集合的索引
     * 2. 增强for循环不能修改数组或集合的元素
     * 3. 增强for循环适用于只需要遍历元素的场景
     */
    public void demonstrateEnhancedForLoop() {
        System.out.println("=== 增强for循环（for-each）演示 ===");
        
        // 遍历数组
        int[] numbers = {1, 2, 3, 4, 5};
        System.out.println("遍历数组:");
        for (int number : numbers) {
            System.out.print(number + " ");
        }
        System.out.println();
        
        // 遍历字符串数组
        String[] names = {"张三", "李四", "王五", "赵六"};
        System.out.println("\n遍历姓名数组:");
        for (String name : names) {
            System.out.println("姓名: " + name);
        }
        
        System.out.println();
    }
    
    /**
     * 演示循环嵌套的使用
     * 难点：多层循环中变量命名和控制的复杂性
     * 注意事项：
     * 1. 嵌套循环要注意变量命名，避免混淆
     * 2. 内层循环的执行次数是外层循环次数与内层循环次数的乘积
     * 3. 过深的嵌套会影响代码可读性和性能
     */
    public void demonstrateNestedLoops() {
        System.out.println("=== 循环嵌套演示 ===");
        
        // 打印九九乘法表
        System.out.println("九九乘法表:");
        for (int i = 1; i <= 9; i++) {
            for (int j = 1; j <= i; j++) {
                System.out.print(j + "*" + i + "=" + (i * j) + "\t");
            }
            System.out.println();  // 换行
        }
        
        // 查找二维数组中的元素
        int[][] matrix = {
            {1, 2, 3},
            {4, 5, 6},
            {7, 8, 9}
        };
        
        System.out.println("\n查找二维数组中的元素5:");
        boolean found = false;
        outerLoop:  // 标签，用于break语句
        for (int i = 0; i < matrix.length; i++) {
            for (int j = 0; j < matrix[i].length; j++) {
                if (matrix[i][j] == 5) {
                    System.out.println("在位置[" + i + "][" + j + "]找到元素5");
                    found = true;
                    break outerLoop;  // 跳出外层循环
                }
            }
        }
        
        if (!found) {
            System.out.println("未找到元素5");
        }
        
        System.out.println();
    }
    
    /**
     * 演示跳转语句的使用
     * 难点：break、continue和return语句在不同场景下的使用
     * 注意事项：
     * 1. break用于跳出循环或switch语句
     * 2. continue用于跳过当前循环的剩余部分，直接进入下一次循环
     * 3. return用于从方法中返回
     * 4. 可以使用标签来控制多层循环中的跳转
     */
    public void demonstrateJumpStatements() {
        System.out.println("=== 跳转语句演示 ===");
        
        // break语句演示
        System.out.println("break语句演示（查找数组中第一个偶数）:");
        int[] arr = {1, 3, 5, 8, 9, 12};
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] % 2 == 0) {
                System.out.println("在索引" + i + "处找到第一个偶数: " + arr[i]);
                break;  // 找到后跳出循环
            }
        }
        
        // continue语句演示
        System.out.println("\ncontinue语句演示（打印奇数）:");
        for (int i = 1; i <= 10; i++) {
            if (i % 2 == 0) {
                continue;  // 跳过偶数
            }
            System.out.print(i + " ");
        }
        System.out.println();
        
        // 带标签的break和continue
        System.out.println("\n带标签的跳转语句演示:");
        outer:  // 外层循环标签
        for (int i = 1; i <= 3; i++) {
            System.out.println("外层循环 i = " + i);
            for (int j = 1; j <= 5; j++) {
                if (j == 3) {
                    System.out.println("  在内层循环中遇到j=3，跳出外层循环");
                    break outer;  // 跳出外层循环
                }
                System.out.println("  内层循环 j = " + j);
            }
        }
        
        System.out.println();
    }
}